package com.wm.picture.service;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wm.blog_common.base.BeanUtils;
import com.wm.blog_common.bean.PageHelper;
import com.wm.blog_common.bean.QueryPage;
import com.wm.blog_common.domain.TFileDO;
import com.wm.blog_common.entity.TFile;
import com.wm.blog_common.enums.DeleteFlag;
import com.wm.blog_common.result.Result;
import com.wm.blog_common.util.DateUtil;
import com.wm.blog_common.util.FileTypeUtil;
import com.wm.blog_common.util.ObjectValidateUtil;
import com.wm.blog_config.util.QiNiuUtil;
import com.wm.picture.dao.TFileDAO;
import com.wm.picture.query.TFileQuery;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * <p>
 * 文件表 服务实现类
 * </p>
 *
 * @author 半卷流年
 * @since 2020-03-26
 */
@Service
@Slf4j
public class TFileService{
    @Autowired
    private TFileDAO tFileDAO;

    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;


    /**
     * 根据ID查询
     * @param id
     * @return
     */
    public Result<TFileDO> selectById(Long id){
        return Result.success(BeanUtils.copyProperties(tFileDAO.getById(id),TFileDO.class));
    }

    /**
    * 根据ID删除
    * @param id
    * @return
    */
    public Result deleteById(Long id){
        return tFileDAO.removeById(id)?Result.success():Result.failure();
    }

    /**
    * 添加
    * @param tFile
    * @return
    */
    public Result insert(TFile tFile){
        return tFileDAO.save(tFile)?Result.success():Result.failure();
    }

    /**
    * 修改
    * @param tFile
    * @return
    */
    public Result update(TFile tFile){
        return tFileDAO.updateById(tFile)?Result.success():Result.failure();
    }

    /**
    * 统计总数
    *
    * @param query
    * @return
    */
    public Result<Integer> count(TFileQuery query) {
        return Result.success(tFileDAO.count(this.combineQuery(query)));
    }

    /**
    * 列表查询
    * @param query
    * @return
    */
    public Result<List<TFileDO>> list(TFileQuery query){
        return Result.success(BeanUtils.copyListProperties(tFileDAO.list(this.combineQuery(query)),TFileDO.class));
    }
    /**
    * 分页查询
    * @param page
    * @return
    */
    public Result<Page<TFileDO>> page(QueryPage page, TFileQuery query){
        return Result.success(PageHelper.newPage(tFileDAO.page(page,this.combineQuery(query)),TFileDO.class));
    }

    /**
    * 组装查询条件
    *
    * @param query
    * @return
    */
    private QueryWrapper<TFile> combineQuery(TFileQuery query) {
        QueryWrapper<TFile> wrapper = new QueryWrapper<>();
        //todo 查询条件 wrapper.eq("字段名","值")
        return wrapper;
    }


    /**
     * id批量查询
     * @param idList
     * @return
     */
    public Result<List<TFile>> getByIdList(List<Long> idList) {
        if(CollectionUtils.isEmpty(idList)){
            return Result.success(Collections.emptyList());
        }
        List<TFile> list = Optional.ofNullable((List<TFile>)tFileDAO.listByIds(idList)).orElse(Collections.emptyList());
        return Result.success(list);
    }


    /**
     * 文件上传七牛云，保存数据到mysql
     * @return
     */
    public Result uploadFile(MultipartFile file) {
        //文件名称
        String filename = file.getOriginalFilename();
        //文件大小
        long fileSize = file.getSize();
        //文件扩展名称
        Map<String, String> map = FileTypeUtil.FILE_TYPE_MAP;
        String type = file.getContentType();
        //上传到七牛云
        CompletableFuture<String> accept = CompletableFuture.supplyAsync(() -> {
            InputStream inputStream = null;
            try {
                inputStream = file.getInputStream();
            } catch (IOException e) {
                log.error("获取文件流失败:{}",e.getMessage(),e);
            }
            return QiNiuUtil.uploadFile(inputStream);
        }, threadPoolTaskExecutor).thenApplyAsync(result -> {
            if (result.isSuccess()) {
                String qiNiuUrl = result.getData();
                QueryWrapper<TFile> wrapper = new QueryWrapper<>();
                wrapper.eq("qi_niu_url",qiNiuUrl);
                wrapper.last("limit 1");
                TFile oldFile = Optional.ofNullable(tFileDAO.getOne(wrapper)).orElse(new TFile());
                if(!ObjectUtils.isEmpty(oldFile.getId())){
                    return qiNiuUrl;
                }
                TFile tFile = new TFile();
                //tFile.setAdminId(query.getAdminId());
               // tFile.setUserId(query.getUserId());
                tFile.setPicName(filename);
                tFile.setPicExpandedName(type);
                tFile.setQiNiuUrl(qiNiuUrl);
                tFile.setStatus(DeleteFlag.ENABLE.getValue());
                Date now = DateUtil.getCurrentDate();
                tFile.setPicUrl(qiNiuUrl);
                tFile.setFileSize(fileSize);
                boolean save = tFileDAO.save(tFile);
                log.info("文件处理结果：{}", save);
            }
            return result.getData();
        });
        try {
            //最长等待5s
            String url = accept.get(5, TimeUnit.SECONDS);
            return Result.success(url);
        } catch (Exception e) {
            log.error("文件处理超时:{}",e.getMessage(),e);
            return Result.failure();
        }
    }

    public Result testUpload(MultipartFile file) {
        try {
            Result<String> result = QiNiuUtil.uploadFile(file.getInputStream());
            return result;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return Result.success();
    }
}







